/* Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.flowable.app.rest.runtime.cus;

import cmbchina.util.AjaxJson;
import cmbchina.util.db.FlowDb;
import org.apache.commons.lang3.StringUtils;
import org.flowable.app.domain.editor.Flow;
import org.flowable.app.domain.editor.FlowForm;
import org.flowable.app.repository.editor.CusFlowFormRepository;
import org.flowable.app.repository.editor.CusFlowRepository;
import org.flowable.app.service.exception.BadRequestException;
import org.flowable.app.service.runtime.FlowableTaskFormService;
import org.flowable.app.service.runtime.FlowableTaskQueryService;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.SequenceFlow;
import org.flowable.bpmn.model.StartEvent;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.impl.HistoryServiceImpl;
import org.flowable.engine.impl.RepositoryServiceImpl;
import org.flowable.engine.impl.TaskServiceImpl;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.form.api.FormRepositoryService;
import org.flowable.form.api.FormService;
import org.flowable.form.model.FormModel;
import org.flowable.rest.exception.FlowableConflictException;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Collection;
import java.util.List;

//import org.flowable.app.model.runtime.SaveFormRepresentation;

/**
 * 流程运行的状态
 * @author Joram Barrez
 */
@RestController
@RequestMapping("/rest/flow-run")
public class CusFlowRunResource {

    private static final Logger LOGGER = LoggerFactory.getLogger(CusFlowRunResource.class);
    @Autowired
    protected FlowableTaskFormService taskFormService;
    @Autowired
    protected TaskServiceImpl taskService;
    @Autowired
    protected HistoryServiceImpl historyService;
    @Autowired
    protected RepositoryServiceImpl repositoryService;
    @Autowired
    protected FlowableTaskQueryService taskQueryService;
    @Autowired
    protected FormService formService;
    @Autowired
    protected RuntimeService runtimeService;
    @Autowired
    private CusFlowRepository cusFlowRepository;
    @Autowired
    private CusFlowFormRepository cusFlowFormRepository;

    /**
     * 获取流程状态
     * @param processInstanceId
     * @return
     */
    @RequestMapping(value = "/flowState/{processInstanceId}", method = RequestMethod.GET, produces = "application/json")
    public Flow geFlowForm(@PathVariable String processInstanceId) {


        List<Flow> flowList = cusFlowRepository.selectFlowByProcessInstId(processInstanceId);
        if(flowList!=null&&flowList.size()>0){
            return flowList.get(0);
        }
        return null;
    }



    /**
     * 获取流程所有节点的状态
     * @param processInstanceId
     * @return
     */
    @RequestMapping(value = "/flowTaskState/{processInstanceId}", method = RequestMethod.GET, produces = "application/json")
    public List<FlowForm> getFlowTaskForm(@PathVariable String processInstanceId) {


        List<FlowForm> flowList = cusFlowFormRepository.selectFlowFormByProcessInstId(processInstanceId);

        return flowList;
    }

    /**
     * 根据spp的key获取所有流程实例信息
     * @param deploymentKey
     * @return
     */
    @RequestMapping(value = "/processInstances/{deploymentKey}/{state}", method = RequestMethod.GET, produces = "application/json")
    public List<Flow> selectFlowByDeploymentKey(@PathVariable String deploymentKey,@PathVariable String state) {


        Flow flow = new Flow();
        flow.setDeploymentKey(deploymentKey);
        if(state!=null&&!"0".equals(state)){
            flow.setState(Integer.parseInt(state));
        }
        List<Flow> flowList = cusFlowRepository.selectFlowByDeploymentKeyAndState(flow);

        return flowList;
    }

    /**
     * 判断流程初始节点是否有绑定表单
     * @param processDefinitionId
     * @return
     */
    @RequestMapping(value = "/flowStartFormKey/{processDefinitionId}", method = RequestMethod.GET, produces = "application/json")
    public AjaxJson flowStartFormKey(@PathVariable String processDefinitionId) {


        AjaxJson ajaxJson = new AjaxJson();
        BpmnModel pojoModel = repositoryService.getBpmnModel(processDefinitionId);
        Collection<FlowElement> flowElements = pojoModel.getMainProcess().getFlowElements();
        ajaxJson.setSuccess(false);
        for(FlowElement e : flowElements) {
            if(!(e instanceof SequenceFlow)){
                String type = e.getClass().getSimpleName();
                if("StartEvent".equals(type)){

                    StartEvent startEvent = (StartEvent) e;
                    if(StringUtils.isNotBlank(startEvent.getFormKey())){
                        ajaxJson.setSuccess(true);
                        ajaxJson.setMsg(startEvent.getFormKey());
                    }
                }
            }


        }
        return ajaxJson;
    }



    /**
     * 停止/回复流程
     * @param processInstId
     * @param state
     * @return
     */
    @RequestMapping(value = "/changeFlow/{processInstId}/{state}", method = RequestMethod.POST, produces = "application/json")
    public AjaxJson stopFlow(@PathVariable String processInstId, @PathVariable String state) {
        AjaxJson ajaxJson = new AjaxJson();
        //暂停
        if("stop".equals(state)){
            ProcessInstance processInstance =  runtimeService.createProcessInstanceQuery().processInstanceId(processInstId).singleResult();
            if (processInstance.isSuspended()) {
                throw new FlowableConflictException("Process instance with id '" + processInstance.getId() + "' is already suspended.");
            }
            runtimeService.suspendProcessInstanceById(processInstId);
            FlowDb.updateFlowState(3, processInstId);
        }else{//恢复
            FlowDb.updateFlowState(1, processInstId);
        }

//        startRequest.setName("zm-测试任务名称");

        return ajaxJson;
    }


    /**
     * 查看流程所有控制台日志
     * @param processInstId
     * @return
     */
    @RequestMapping(value = "/querySysLog/{processInstId}/{state}", method = RequestMethod.POST, produces = "application/json")
    public AjaxJson querySysLog(@PathVariable String processInstId) {
        AjaxJson ajaxJson = new AjaxJson();
//        ProcessInstance processInstance =  historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstId).singleResult();
//        taskService.getlo
//        //暂停
//        if("stop".equals(state)){
//
//            if (processInstance.isSuspended()) {
//                throw new FlowableConflictException("Process instance with id '" + processInstance.getId() + "' is already suspended.");
//            }
//            runtimeService.suspendProcessInstanceById(processInstId);
//            FlowDb.updateFlowState(3, processInstId);
//        }else{//恢复
//            FlowDb.updateFlowState(1, processInstId);
//        }

//        startRequest.setName("zm-测试任务名称");

        return ajaxJson;
    }


}
